PackerでAMIをぱかっと作ってみた
今回はPackerを使ってAMIを作ってみました。ですのでその記録をブログに書いておきます。
Packerとは
HashiCorp社が出している、AWS、GCP、Azure、Docker、VirtualBoxといった様々な環境で使用できるマシンイメージを自動で作ることができるツールです。
今回はAWS上で検証したのでAMIを作成できました。
実際にAMIを作成する手順は下記のような流れになりました。
- 事前準備
- テンプレートの作成
- AMIの作成
事前準備
Packerのインストール
macOSだと下記コマンドでインストールできます。
$ brew install packer
またソースコードも公開されているのでコードを元にコンパイルすることもできます。
IAM Userの準備
CLIアクセスできるIAM Userの作成とAccess Key
とSecret Access Key
をお手元に準備してください。
テンプレートの作成
Packerではマシンイメージの作成をテンプレートと呼ばれるファイルを元に作成します。
json形式のファイルで今回定義したのはざっくりとこんな内容です。
Key | Value | Description |
---|---|---|
type | amazon-ebs | 作成するマシンイメージのデプロイ先 |
region | ap-northeast-1 | AMIを作成するリージョン |
source_ami | ami-0f9ae750e8274075b | 作成するAMIのベースになるAMI(今回はAmazonLinux2) |
ssh_username | ec2-user | インスタンス起動時にSSH接続するためのユーザ |
ami_name | packer101-ami | amiにつける名前 |
provisioners | 省略 | AMIイメージ作成時に実行するコマンド |
そしてテンプレートファイルの中身はこんな感じです。
{ "builders": [ { "type": "amazon-ebs", "region": "ap-northeast-1", "source_ami": "ami-0f9ae750e8274075b", "instance_type": "t2.micro", "ssh_username": "ec2-user", "ami_name": "packer101-ami" } ], "provisioners": [ { "type": "shell", "inline": [ "sudo yum -y update", "sudo yum -y install httpd", "sudo systemctl start httpd && sudo systemctl enable httpd" ] } ] }
それでは実際に AMIを作成する...前にテンプレートの構文があっているかを確認しましょう。
$ packer validate packer101.json Template validated successfully.
こんな感じの出力が出たら構文に問題はありません。エラーが出たら修正して、実際にAMIをビルドしましょう!
AMI の作成
下記のコマンドでAMIが作成されます。
AWS_*
のところには先ほど作成したIAM Userの情報を入れましょう。
$ export AWS_ACCESS_KEY_ID="XXXXXXXXXXXXXXX" $ export AWS_SECRET_ACCESS_KEY="YYYYYYYYYYYYYYYYYYYYYYYYYYYYYY" $ packer build packer101.json
buildを実行すると、EC2インスタンスが起動され、起動されたEC2インスタンスを元にAMIが作成されます。 実際にビルドの途中でEC2インスタンスを確認してみると...。
$ aws ec2 describe-instances --query Reservations[].Instances[].Tags[].Value Packer Builder
Packer Builder
というEC2インスタンスが立ち上がっていますね。
そしてこれを元にAMIが作成されていきます。
ビルドの出力が下記のように出たらAMIが使用可能になっています。
==> Builds finished. The artifacts of successful builds are: --> amazon-ebs: AMIs were created: ap-northeast-1: ami-xxxxxxxxxxxx
これを元にインスタンスを立ち上げればhttpd が起動してあるインスタンスが出来上がります。
実際にアクセスしてみると、テストページが無事表示されました!
Switch Role してAMIの作成をする
Switch RoleしないとAWS CLIを使えないから、上の方法は使えないという場合も安心してください。
先ほどのテンプレートに profile
を追加して、そこにスイッチ先のRoleを書けばいいだけなのです。
ついでにMFAの対応も書いておきます。こちらもちょろっと追記すれば問題ありません。
先ほどのテンプレートファイルに下記のような変更を加えれば大丈夫です。
{ "variables": { "mfa_code": "000000" }, "builders": [ { ~~~ "profile": "switch", "mfa_code": "{{user `mfa_code`}}", ~~~ } ] }
このように変更することでMFA対応と、 switch
という名前のロールにスイッチして実行してくれます。
そしたらAMIを作成しましょう。変数のmfa_code
に6桁の数字を渡せばOKです。
$ packer build -var "mfa_code=123456" packer101.json
テンプレートをちょっと便利にする
今のテンプレートでも十分に便利ですけどそれよりちょっと便利にして新しいAMIを作りましょう。
なのでまずは、既存のAMIを削除します。
$ aws ec2 deregister-image --image-id ami-xxxxxxxxxxxx
消したらテンプレートファイルを書き換えます。
具体的にはベースとなるAMIをいつでも最新のAmazon Linux 2にします。
{ "builders": [ { "type": "amazon-ebs", "region": "ap-northeast-1", "instance_type": "t2.micro", "ssh_username": "ec2-user", "ami_name": "packer101-ami", "source_ami_filter": { "filters": { "name": "amzn2-ami-hvm-*-x86_64-gp2" }, "owners": ["137112412989"], "most_recent": true } } ], "provisioners": [ { "type": "shell", "inline": [ "sudo yum -y update", "sudo yum -y install httpd", "sudo systemctl start httpd && sudo systemctl enable httpd" ] } ] }
先ほどまで ami_name
で直接AMI IDを指定していたのをフィルターでうまいこと最新のものを取得するように変更します。
それではもう一度AMIを作成します。
$ packer validate packer101.json $ packer build packer101.json
buildで出力された AMI IDを元に生成がされているかを確認しましょう。
$ aws ec2 describe-images --image-id ami-xxxxxxxxxxx --query Images[].Name packer101-ami
問題なくAMIが作成されましたね。
最後に
今回はPackerの素振りということであまり複雑なことはやりませんでした。
ですが、変数やAnsibleなどなど様々な機能がPackerでは使用できます。
AMIのイメージをコードで管理できるのは非常に良さげです。